/**
 * Copyright (c) 2015-2017, Henry Yang 杨勇 (gismail@foxmail.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.mapfinal.server.auth.model;

import java.util.List;

import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Model;
import com.lambkit.Lambkit;
import com.lambkit.common.service.ServiceKit;
import com.lambkit.db.sql.column.Column;
import com.mapfinal.server.MapfinalServerConfig;
import com.mapfinal.server.auth.UserService;
import com.mapfinal.server.auth.service.impl.UserServiceImpl;
import com.mapfinal.server.kit.JsoupFilter;
import com.lambkit.plugin.auth.IUser;

/**
 * @author yangyong 
 * @website: www.lambkit.com
 * @email: gismail@foxmail.com
 * @date 2020-09-23
 * @version 1.0
 * @since 1.0
 */
public class User extends UserBase<User> implements IUser {

	private static final long serialVersionUID = 1L;
	
	public static UserService service() {
		return ServiceKit.inject(UserService.class, UserServiceImpl.class);
	}
	
	public static UserCriteria sql() {
		return new UserCriteria();
	}
	
	public static UserCriteria sql(Column column) {
		UserCriteria that = new UserCriteria();
		that.add(column);
        return that;
    }

	public User() {
		MapfinalServerConfig config = Lambkit.config(MapfinalServerConfig.class);
		String dbconfig = config.getDbConfig();
		if(StrKit.notBlank(dbconfig)) {
			this.use(dbconfig);
		}
	}
	
	public static final int STATUS_LOCK_ID = -1;	// 锁定账号，无法做任何事情
	public static final int STATUS_REG = 0;			// 注册、未激活
	public static final int STATUS_OK = 1;			// 正常、已激活

	@Override
	public boolean checkPassword(String pass) {
		// TODO Auto-generated method stub
		return pass.equals(this.getStr("user_pass"));
	}

	@Override
	public void createPassword(String arg0) {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	public void updatePassword(String arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public String getClassName() {
		// TODO Auto-generated method stub
		return this.getClass().getName();
	}

	@Override
	public Model<?> getModel() {
		// TODO Auto-generated method stub
		return this;
	}

	@Override
	public String getName() {
		// TODO Auto-generated method stub
		return getUserLogin();
	}
	
	@Override
	public String getPhone() {
		// TODO Auto-generated method stub
		return getUserPhone();
	}

	@Override
	public String getEmail() {
		// TODO Auto-generated method stub
		return getUserEmail();
	}

	@Override
	public String getPassword() {
		// TODO Auto-generated method stub
		return getUserPass();
	}

	@Override
	public String getShowName() {
		// TODO Auto-generated method stub
		return getUserNicename();
	}

	@Override
	public int getType() {
		// TODO Auto-generated method stub
		return getUserType();
	}

	@Override
	public boolean isLocked() {
		// TODO Auto-generated method stub
		return getUserStatus()!=null && getUserStatus()==1 ? false : true;
	}

	@Override
	public IUser removeSecretInfo() {
		// TODO Auto-generated method stub
		this.remove("user_pass");
		this.remove("salt");
		return this;
	}
	
	///////////////////////////////////////

	public String getNickName() {
		// TODO Auto-generated method stub
		return getUserNicename();
	}
	
	public void setNickName(String text) {
		// TODO Auto-generated method stub
		setUserNicename(text);
	}

	public String getUserName() {
		// TODO Auto-generated method stub
		return getUserLogin();
	}
	
	public int getStatus() {
		return getUserStatus();
	}
	
	public boolean isStatusOk() {
		return getStatus() == STATUS_OK;
	}

	public boolean isStatusReg() {
		return getStatus() == STATUS_REG;
	}

	public boolean isStatusLockId() {
		return getStatus() == STATUS_LOCK_ID;
	}

	/**
	 * 过滤掉 nickName 中的 html 标记，恶意脚本
	 */
	protected void filter(int filterBy) {
		JsoupFilter.filterAccountNickName(this);
	}
	
	
	public User removeSensitiveInfo() {
		remove("user_pass", "salt");
		return this;
	}
	
	private boolean login = false;
	private List<Role> roles;
	private List<AuthRule> rules;

	public Boolean hasRole(int roleid) {
		// TODO Auto-generated method stub
		if(roles!=null && roles.size() > 0) {
			for (Role role : roles) {
				if(role.getId().equals(Integer.valueOf(roleid))) {
					return true;
				}
			}
			return false;
		} else {
			return RoleUser.service().hasRole(getId(), roleid);
		}
	}

	public Boolean hasRole(String roleName) {
		// TODO Auto-generated method stub
		if(StrKit.isBlank(roleName)) return false;
		if(roles!=null && roles.size() > 0) {
			for (Role role : roles) {
				if(role.getName().equals(roleName)) {
					return true;
				}
			}
			return false;
		} else {
			return RoleUser.service().hasRole(getId(), roleName);
		}
	}

	public Boolean lacksRole(String roleName) {
		// TODO Auto-generated method stub
		if(StrKit.isBlank(roleName)) return true;
		if(roles!=null && roles.size() > 0) {
			for (Role role : roles) {
				if(role.getName().equals(roleName)) {
					return false;
				}
			}
			return true;
		} else {
			return !RoleUser.service().hasRole(getId(), roleName);
		}
	}

	public boolean hasAnyRoles(String roleNames) {
		// TODO Auto-generated method stub
		if(StrKit.isBlank(roleNames)) return false;
		roleNames = "," + roleNames + ",";
		if(roles!=null && roles.size() > 0) {
			for (Role role : roles) {
				if(roleNames.indexOf(","+role.getName()+",") > 0) {
					return true;
				}
			}
			return false;
		} else {
			return RoleUser.service().hasAnyRoles(getId(), roleNames);
		}
	}

	public boolean hasAllRoles(String roleNames) {
		// TODO Auto-generated method stub
		if(StrKit.isBlank(roleNames)) return false;
		roleNames = "," + roleNames + ",";
		if(roles!=null && roles.size() > 0) {
			for (Role role : roles) {
				roleNames.replace(","+role.getName()+",", ",");
			}
			if(",".equals(roleNames)) {
				return true;
			} else {
				return false;
			}
		} else {
			return RoleUser.service().hasAllRoles(getId(), roleNames);
		}
	}

	public Boolean hasRule(int ruleid) {
		// TODO Auto-generated method stub
		if(hasRole(1)) return true;
		if(rules!=null && rules.size() > 0) {
			for (AuthRule rule : rules) {
				if(rule.getId().equals(Integer.valueOf(ruleid))) {
					return true;
				}
			}
			return false;
		} else {
			return AuthAccess.service().hasRule(getId(), ruleid);
		}
	}

	public boolean hasRule(String permission) {
		// TODO Auto-generated method stub
		if(hasRole(1)) return true;
		if(StrKit.isBlank(permission)) return false;
		if(rules!=null && rules.size() > 0) {
			for (AuthRule rule : rules) {
				if(rule.getName().equals(permission)) {
					return true;
				}
			}
			return false;
		} else {
			return AuthAccess.service().hasRule(getId(), permission);
		}
	}

	public boolean lacksRule(String permission) {
		// TODO Auto-generated method stub
		if(hasRole(1)) return false;
		if(StrKit.isBlank(permission)) return true;
		if(rules!=null && rules.size() > 0) {
			for (AuthRule rule : rules) {
				if(rule.getName().equals(permission)) {
					return false;
				}
			}
			return true;
		} else {
			return !AuthAccess.service().hasRule(getId(), permission);
		}
	}

	public boolean hasAnyRules(String permissions) {
		// TODO Auto-generated method stub
		if(hasRole(1)) return true;
		if(StrKit.isBlank(permissions)) return false;
		permissions = "," + permissions + ",";
		if(rules!=null && rules.size() > 0) {
			for (AuthRule rule : rules) {
				if(permissions.indexOf(","+rule.getName()+",") > 0) {
					return true;
				}
			}
			return false;
		} else {
			return AuthAccess.service().hasAnyRules(getId(), permissions);
		}
	}

	public boolean hasAllRules(String permissions) {
		// TODO Auto-generated method stub
		if(hasRole(1)) return true;
		if(StrKit.isBlank(permissions)) return false;
		permissions = "," + permissions + ",";
		if(rules!=null && rules.size() > 0) {
			for (AuthRule rule : rules) {
				permissions.replace(","+rule.getName()+",", ",");
			}
			if(",".equals(permissions)) {
				return true;
			} else {
				return false;
			}
		} else {
			return AuthAccess.service().hasAllRules(getId(), permissions);
		}
	}

	public boolean isLogin() {
		return login;
	}

	public void setLogin(boolean login) {
		this.login = login;
		if(login) {
			roles = Role.service().getRoles(this.getId());
			rules = AuthRule.service().getPermissions(this.getId());
		}
	}

	public List<Role> getRoles() {
		return roles;
	}

	public void setRoles(List<Role> roles) {
		this.roles = roles;
	}

	public List<AuthRule> getRules() {
		return rules;
	}

	public void setRules(List<AuthRule> rules) {
		this.rules = rules;
	}

}
